package gitobject;

import java.io.*;

import core.JitBranch;
import fileoperation.FileCreation;
import sha1.SHA1;
import repository.Repository;

public class Commit extends GitObject{

    private static final long serialVersionUID = -5753132822294252545L;
    protected String tree; 		// the sha1 value of present committed tree
    protected String parent; 	// the sha1 value of the parent commit
    protected String author; 	// the author's name and timestamp
    protected String committer; // the committer's info
    protected String message; 	// the commit memo

    public String getParent(){return parent;}
    public String getTree(){return tree;}
    public String getAuthor(){return author;}
    public String getCommitter(){return committer;}
    public String getMessage(){return message;}

    public Commit(){}
    /**
     * Construct a commit directly from a file.
     * @param
     * author, committer, message鍙傛暟鍦╣it commit鍛戒护閲屽垱寤�
     * @throws Exception
     */
    public Commit(String treeKey, String author, String committer, String message) throws Exception {
        this.fmt = "commit"; 	//type of object
        this.tree = treeKey;
        this.parent = getLastCommit() == null ? "" : getLastCommit(); //null means there is no parent commit.
        this.author = author;
        this.committer = committer;
        this.message = message;

        /*Content of this commit, like this:
         *tree bd31831c26409eac7a79609592919e9dcd1a76f2
         *parent d62cf8ef977082319d8d8a0cf5150dfa1573c2b7
         *author xxx  1502331401 +0800
         *committer xxx  1502331401 +0800
         *淇澧為噺bug
         * */
        this.value = "tree " + this.tree + "\nparent " + this.parent+ "\nauthor " + this.author + "\ncommitter " + this.committer + "\n" + this.message;

        key = genKey();
        compressWrite();

    }

    /**
     * Construct a commit from a built tree.
     * @param
     * author, committer, message鍙傛暟鍦╣it commit鍛戒护閲屽垱寤�
     * @throws Exception
     */
    public Commit(Tree t, String author, String committer, String message) throws Exception {
        this.fmt = "commit"; 	//type of object
        this.tree = t.getKey();
        this.parent = getLastCommit() == null ? "" : getLastCommit(); //null means there is no parent commit.
        this.author = author;
        this.committer = committer;
        this.message = message;

        /*Content of this commit, like this:
         *tree bd31831c26409eac7a79609592919e9dcd1a76f2
         *parent d62cf8ef977082319d8d8a0cf5150dfa1573c2b7
         *author xxx  1502331401 +0800
         *committer xxx  1502331401 +0800
         *淇澧為噺bug
         * */
        this.value = "tree " + this.tree + "\nparent " + this.parent+ "\nauthor " + this.author + "\ncommitter " + this.committer + "\n" + this.message;
        this.key = genKey();
        compressWrite();
    }

    /**
     * Deserialize the commit object from its key(commitId)
     * @param commitId
     * @throws IOException
     */
    public static Commit deserialize(String commitId) throws IOException {
        Commit commit = null;
        try{
            byte[] bytes = deCompress(commitId);
            if(bytes == null) return null;
            ByteArrayInputStream in = new ByteArrayInputStream(bytes);
            ObjectInputStream file = new ObjectInputStream(in);
            commit = (Commit)file.readObject();
            file.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return commit;
    }
    /**
     * Generate the hash value of this commit.
     * @return key
     * */
    public String genKey() throws Exception {
        key = SHA1.getHash(this.value);
        return key;
    }

    public static File getNowHeadFile() throws IOException{
        File HEAD = new File(Repository.getGitDir() + File.separator + "HEAD");
        if(HEAD.exists()){

            String path = getValue(HEAD);

            if(path.length() != 0)
                path = path.substring(5).trim();
            else return null;
            return new File(Repository.getGitDir() + File.separator + path.replace(Tree.treeSeparator, File.separator));
        }
        else return null;
    }



    /**
     * Get the parent commit from the HEAD file.
     * @return
     * @throws IOException
     */
    public static String getLastCommit() throws IOException {
        File branchFile = getNowHeadFile();
        if(branchFile == null) {
            return null;
        }
        else {
            if (branchFile.isFile()) {
                return getValue(branchFile);
            } else {
                return null;
            }
        }
    }

    public String writeToHead() throws IOException{
        File branchFile = getNowHeadFile();
        if(branchFile == null) return null;
        if(!branchFile.exists()){
            FileCreation.createFile(JitBranch.branchPath, JitBranch.getNowBranchName(), key);
            return key;
        }
        else {
            if (branchFile.isFile()) {
                FileWriter fw = new FileWriter(branchFile);
                fw.write(key);
                fw.flush();
                fw.close();
                return key;
            } else {
                return null;
            }
        }
    }
}

